package com.definity.toolkit.web.interceptor;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.caelum.vraptor.view.Results;

import com.definity.security.common.User;
import com.definity.toolkit.message.AccessDenyMessage;
import com.definity.toolkit.security.Security;

public abstract class AbstractSecurityInterceptor implements Interceptor {

	protected final Result result;
	protected final HttpServletRequest request;

	public AbstractSecurityInterceptor(Result result, HttpServletRequest request) {
		this.result = result;
		this.request = request;
	}
	
	@Override
	public boolean accepts(ResourceMethod method) {
		return method.containsAnnotation(Security.class);
	}

	@Override
	public void intercept(InterceptorStack stack, ResourceMethod method, Object instance) throws InterceptionException {
		User user = getUser();
		if (user == null) {
			result.use(Results.http()).sendError(401, new AccessDenyMessage().getMessage());
			return;
		}
		
		Security security = method.getMethod().getAnnotation(Security.class);
		
		List<String> roleNames = Arrays.asList(security.value());
		
		if (hasRoles(user, roleNames)) {
			stack.next(method, instance);
		} else {
			result.use(Results.http()).sendError(403, new AccessDenyMessage().getMessage());
		}
	}

	protected abstract boolean hasRoles(User user, List<String> roleNames);
	
	protected abstract User getUser();

}
